function isObject(value) {
  return typeof value === "object" && value !== null;
}

function hasOwnProperty(target, key) {
  return Object.prototype.hasOwnProperty.call(target, key);
}

function isEqual(newValue, oldValue) {
  return newValue === oldValue;
}

const get = createGetter(), // creator
  set = createSetter(); // creator

function createGetter() {
  return function get(target, key, receiver) {
    const res = Reflect.get(target, key, receiver);
    // todo ......
    console.log("响应式获取：" + target[key]);

    if (isObject(res)) {
      return reactive(res);
    }

    return res;
  };
}

function createSetter() {
  return function set(target, key, value, receiver) {
    const isKeyExist = hasOwnProperty(target, key),
      oldValue = target[key],
      res = Reflect.set(target, key, value, receiver);
    // todo ......

    console.log(isKeyExist, "isKeyExist");
    if (!isKeyExist) {
      console.log("响应式新增：" + value);
    } else if (!isEqual(value, oldValue)) {
      console.log("响应式修改：" + key + "=" + value);
    }

    return res;
  };
}

function reactive(target) {
  return createReactiveObject(target, mutableHandler);
}

function createReactiveObject(target, baseHandler) {
  if (!isObject(target)) {
    return target;
  }

  const observer = new Proxy(target, baseHandler);
  return observer;
}
const mutableHandler = {
  get,
  set,
};
